{-# LANGUAGE ForeignFunctionInterface  #-}
module Libcell where
import Foreign
import Foreign.C
import HCstructures

#include "libcell_wrapper.h"
-- #include "libcell_struct.h"
#include "Mesh_IO/Mesh_IO.h"

double2cfloat :: Double -> CFloat
double2cfloat a= realToFrac a
float2cfloat :: Float -> CFloat
float2cfloat a= realToFrac a
cfloat2float :: CFloat ->Float
cfloat2float a= realToFrac a
int2cuint :: Int -> CUInt
int2cuint a= fromIntegral a
cint2int::CInt->Int
cint2int a=fromIntegral a
int2cint::Int->CInt
int2cint a=fromIntegral a



data VertexT=VertexT{
    vertext_get_id :: ! Int
}
instance Storable VertexT where
    sizeOf _ = #{size VertexT }
    alignment _ = #{alignment VertexT }
    peek ptr=do
        id1 <- peek (#{ptr VertexT , id} ptr)
        id<- return $cint2int id1   
        pure (VertexT id)
    poke ptr (VertexT id)=do
        id1<-return $ int2cint id
        poke (#{ptr VertexT,id} ptr) id1

data CellT=CellT{
    cellt_get_id :: ! Int
}
instance Storable CellT where
    sizeOf _ = #{size CellT }
    alignment _ = #{alignment CellT }
    peek ptr=do
        id <- return.cint2int =<< peek (#{ptr CellT , id} ptr)  
        pure (CellT id)
    poke ptr (CellT id)=do
        poke (#{ptr CellT,id} ptr) $ int2cint id

data MeshT=MeshT{
    mesht_get_id :: ! Int
}
instance Storable MeshT where
    sizeOf _ = #{size MeshT }
    alignment _ = #{alignment MeshT }
    peek ptr=do
        id <- return.cint2int=<<peek (#{ptr MeshT , id} ptr)  
        pure (MeshT id)
    poke ptr (MeshT id)=do
        poke (#{ptr MeshT,id} ptr) $ int2cint id


data FaceT=FaceT{
    facet_get_id :: ! Int
}
instance Storable FaceT where
    sizeOf _ = #{size FaceT }
    alignment _ = #{alignment FaceT }
    peek ptr=do
        id <- return.cint2int=<<peek (#{ptr FaceT , id} ptr)  
        pure (FaceT id)
    poke ptr (FaceT id)=do
        poke (#{ptr FaceT,id} ptr) $ int2cint id



data HalfT=HalfT{
    halft_get_id :: ! Int
}
instance Storable HalfT where
    sizeOf _ = #{size HalfT }
    alignment _ = #{alignment HalfT }
    peek ptr=do
        id <- return.cint2int=<< peek (#{ptr HalfT , id} ptr)  
        pure (HalfT id)
    poke ptr (HalfT id)=do
        poke (#{ptr HalfT,id} ptr) $int2cint id


data Vertex=Vertex{
    vertex_get_id:: !Int,
    vertex_get_point:: !(Ptr Double),
    vertex_get_point_size:: !(Int),
    vertex_get_cells:: !(Ptr Node),
    vertex_get_faces:: !(Ptr Node),
    vertex_get_prop:: !(Ptr ()),
    vertex_get_user_prop:: !(Ptr ()),
    vertex_get_traits:: !VertexT
}

instance Storable Vertex where
    sizeOf _ = #{size Vertex }
    alignment _ = #{alignment Vertex}
    peek ptr=do
        id<-return.cint2int=<<peek (#{ptr Vertex,id} ptr)
        point<- peek (#{ptr Vertex,point} ptr)
        point_size<-return.cint2int=<<peek (#{ptr Vertex,point_size} ptr)
        cells<- peek (#{ptr Vertex,cells} ptr)
        faces<- peek (#{ptr Vertex,faces} ptr)
        prop<- peek (#{ptr Vertex, prop} ptr)
        user_prop <- peek (#{ptr Vertex, user_prop} ptr)
        traits<- peek (#{ptr Vertex,traits} ptr)
        pure (Vertex id point point_size cells faces prop user_prop traits) 
    poke ptr (Vertex id point point_size cells faces prop user_prop traits)=do
        poke (#{ptr Vertex,id} ptr) $ int2cint id
        poke (#{ptr Vertex,point} ptr) point
        poke (#{ptr Vertex,point_size} ptr) $int2cint point_size
        poke (#{ptr Vertex,cells} ptr) cells
        poke (#{ptr Vertex,faces} ptr) faces
        poke (#{ptr Vertex,prop} ptr) prop
        poke (#{ptr Vertex,user_prop} ptr) user_prop
        poke (#{ptr Vertex,traits} ptr ) traits 


data HalfFace=HalfFace{
    halfface_get_id:: !Int,
    halfface_get_vertices:: !(Ptr (Ptr Vertex)),
    halfface_get_vertices_size:: !Int,
    halfface_get_cell:: !(Ptr Cell),
    halfface_get_face:: !(Ptr Face),
    halfface_get_prop:: !(Ptr ()),
    halfface_get_user_prop:: !(Ptr ()),
    halfface_get_traits:: !(HalfT)
    
}
instance Storable HalfFace where
    sizeOf _ = #{size HalfFace}
    alignment _ = #{alignment HalfFace}
    peek ptr= do
        id<- return.cint2int=<<peek (#{ptr HalfFace,id} ptr)
        vertices<- peek (#{ptr HalfFace,vertices} ptr)
        vertices_size <- peek (#{ptr HalfFace,vertices_size} ptr)
        cell <- peek (#{ptr HalfFace,cell} ptr)
        face<- peek (#{ptr HalfFace,face} ptr)
        prop<- peek (#{ptr HalfFace,prop} ptr)
        user_prop<- peek (#{ptr HalfFace,user_prop} ptr)
        traits<- peek (#{ptr HalfFace,traits} ptr)
        pure (HalfFace id vertices vertices_size cell face prop user_prop traits)
    poke ptr (HalfFace id vertices vertices_size cell face prop user_prop traits)=do
        poke (#{ptr HalfFace,id} ptr) $int2cint id
        poke (#{ptr HalfFace, vertices} ptr) vertices
        poke (#{ptr HalfFace,vertices_size} ptr) vertices_size
        poke (#{ptr HalfFace,cell} ptr) cell
        poke (#{ptr HalfFace,face} ptr) face
        poke (#{ptr HalfFace,prop} ptr) prop
        poke (#{ptr HalfFace,user_prop} ptr) user_prop
        poke (#{ptr HalfFace,traits} ptr) traits



data Face=Face{
    face_get_id:: !Int,
    face_get_vertices:: !(Ptr (Ptr Vertex)),
    face_get_vertices_size:: !Int,
    face_get_halffaces:: ![Ptr HalfFace],
    face_get_prop:: !(Ptr ()),
    face_get_user_prop:: !(Ptr ()),
    face_get_triats:: !FaceT
}
instance Storable Face where
    sizeOf _ = #{size Face}
    alignment _ = #{alignment Face}
    peek ptr =do
        id<- return.cint2int =<< peek (#{ptr Face,id} ptr)
        vertices<- peek (#{ptr Face,vertices} ptr)
        vertices_size<- peek (#{ptr Face,vertices_size} ptr)
        halffaces<- peekArray 2 (#{ptr Face,halffaces} ptr)
        prop<- peek (#{ptr Face,prop} ptr)
        user_prop<- peek (#{ptr Face,user_prop} ptr)
        traits<- peek (#{ptr Face,traits} ptr)
        pure (Face id vertices vertices_size halffaces prop user_prop traits) 
    poke ptr (Face id vertices vertices_size halffaces prop user_prop traits)=do
        poke (#{ptr Face,id} ptr) $ int2cint id
        poke (#{ptr Face,vertices} ptr) vertices
        poke (#{ptr Face,vertices_size} ptr) $ int2cint vertices_size
        pokeArray (#{ptr Face,halffaces} ptr) halffaces
        poke (#{ptr Face,prop} ptr) prop
        poke (#{ptr Face,user_prop} ptr) user_prop
        poke (#{ptr Face,traits} ptr) traits


data Cell=Cell{
    cell_get_id:: !Int,
    cell_get_vertices:: !(Ptr (Ptr Vertex)),
    cell_get_vertices_size:: !Int,
    cell_get_halffaces:: !(Ptr Node),
    cell_get_prop:: !(Ptr ()),
    cell_get_user_prop:: !(Ptr ()),
    cell_get_traits:: !CellT
}

instance Storable Cell where
    sizeOf _ = #{size Cell}
    alignment _ = #{alignment Cell}
    peek ptr=do
        id<- return.cint2int=<<peek (#{ptr Cell,id} ptr) 
        vertices<- peek (#{ptr Cell,vertices} ptr)
        vertices_size<-return.cint2int =<< peek (#{ptr Cell,vertices_size} ptr) 
        halffaces<- peek (#{ptr Cell,halffaces} ptr)
        prop<- peek (#{ptr Cell,prop} ptr)
        user_prop <- peek (#{ptr Cell,user_prop} ptr)
        traits<- peek (#{ptr Cell,traits} ptr)
        pure (Cell id vertices vertices_size halffaces prop user_prop traits)
    poke ptr (Cell id vertices vertices_size halffaces prop user_prop traits)=do
        poke (#{ptr Cell,id} ptr) $ int2cint id
        poke (#{ptr Cell,vertices} ptr) vertices
        poke (#{ptr Cell,vertices_size} ptr)$ int2cint vertices_size
        poke (#{ptr Cell,halffaces} ptr) halffaces
        poke (#{ptr Cell, prop} ptr) prop
        poke (#{ptr Cell, user_prop} ptr) user_prop
        poke (#{ptr Cell,traits }ptr) traits


  

foreign import ccall "get_rb_tree_node"
        get_rb_tree_node::IO (Ptr (RB_Tree_Node))


foreign import ccall "test_cut"
    test_cut::IO()

foreign import ccall "get_vertex"
    get_vertex:: IO (Ptr Vertex)


my_test:: Ptr a->IO ()
my_test nullPtr=putStrLn "libooooooo"   

mytest::IO()
mytest=do
    node<- get_rb_tree_node
    node_ <- peek node 
    my_test $ rb_tree_node_get_left node_
